package api

import (
	"io"
	"errors"
	"math/big"
	"kumachan/standalone/rx"
	"kumachan/standalone/rpc"
	"kumachan/standalone/util"
	"kumachan/interpreter/runtime/rt"
)


func __Error(msg string, data_ rt.Value) error {
	var data_items = rt.ListFrom(data_)
	if data_items.Length() == 0 {
		return errors.New(msg)
	}
	var data = make(map[string] string)
	data_items.ForEach(func(i uint, p_ rt.Value) {
		var p = p_.(rt.TupleValue)
		var k = p.Elements[0].(string)
		var v = p.Elements[1].(string)
		data[k] = v
	})
	return util.ErrorWithExtraData(&rpc.CustomError {
		Desc: msg,
		Data: data,
	})
}

func __ErrorToString(err error) string {
	return err.Error()
}
func __ErrorData(e error, key string) string {
	var e_with_extra, with_extra = e.(util.ErrorWithExtraData)
	if with_extra {
		var value, exists = e_with_extra.LookupExtraData(key)
		if exists {
			return value
		} else {
			return ""
		}
	} else {
		return ""
	}
}

func __ErrorWrap(e error, f rt.Value, h rt.InteropContext) error {
	var wrap_desc = func(desc string) string {
		var wrapped_str = h.Call(f, desc).(string)
		return wrapped_str
	}
	return util.WrapError(e, wrap_desc)
}

func __ErrorNumOfIoBytes(err error) *big.Int {
	var rw, is_rw = err.(*rx.ReadWriteError)
	if is_rw {
		return util.GetNumberUint(uint(rw.BytesTransferred))
	} else {
		return big.NewInt(0)
	}
}
func __ErrorIsEOF(err error) rt.EnumValue {
	return rt.ToBool(err == io.EOF)
}
func __ErrorIsClosedPipe(err error) rt.EnumValue {
	return rt.ToBool(err == io.ErrClosedPipe)
}

// TODO: should be moved to another file
func __None() rt.Value {
	return nil
}


